/**
 * Project: TacticaPescaditos
 * File: StateMachine.java
 */
package org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup.fsm;

import org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup.fsm.state.State;
import org.javahispano.javacup.tacticas_aceptadas.Pescaditos.com.chidotronics.javacup.messages.Telegram;

/**
 * @author Carlos Alberto class: StateMachine
 */
/**
 * @author Carlos Alberto
 * class: StateMachine
 * @param <E>
 */
public class StateMachine<E> {

	/**
	 * @param owner
	 */
	public StateMachine(E owner) {
		this.owner = owner;
	}

	private E owner;

	private State<E> currentState;

	private State<E> previousState;

	private State<E> globalState;

	/**
	 * @return the currentState
	 */
	public State<E> getCurrentState() {
		return currentState;
	}

	/**
	 * @param currentState
	 *            the currentState to set
	 */
	public void setCurrentState(State<E> currentState) {
		this.currentState = currentState;
	}

	/**
	 * @return the previousState
	 */
	public State<E> getPreviousState() {
		return previousState;
	}

	/**
	 * @param previousState
	 *            the previousState to set
	 */
	public void setPreviousState(State<E> previousState) {
		this.previousState = previousState;
	}

	/**
	 * @return the globalState
	 */
	public State<E> getGlobalState() {
		return globalState;
	}

	/**
	 * @param globalState
	 *            the globalState to set
	 */
	public void setGlobalState(State<E> globalState) {
		this.globalState = globalState;
	}

	
	/**
	 * @param newState change the current state.
	 * @throws NullPointer exception if the newState is null.
	 */
	public void changeState(State<E> newState) {

		if (newState == null) {
			throw new NullPointerException();
		}

		this.previousState = this.currentState;

		this.currentState.exit(owner);

		this.currentState = newState;

		this.currentState.enter(owner);
	}
	
	/**
	 * change state back to the previous state
	 * @throws NullPointer exception if the newState is null.
	 */
	public void  revertToPreviousState(){
	    changeState(previousState);
	  }
	
	
	 /**
	 * @param msg
	 * @return
	 */
	public boolean handleMessage(Telegram msg) {

	    if (currentState != null && currentState.onMessage(owner, msg))
	    {
	      return true;
	    }
	  
	    if (globalState != null && globalState.onMessage(owner, msg))
	    {
	      return true;
	    }

	    return false;
	  }
	 
	 /**
	 * @param st
	 * @return true if classes of currentState and st objects are equals, 
	 * 				false if st or currentState are null or not equals
	 */
	public boolean isInState(State<E> st)
	  {
		 if (currentState== null || st == null){
			 return false;
		 }
	    return ( currentState.getClass().equals(st.getClass()) );
	  }

	public void update() {

	    if(globalState != null) {
	    	globalState.execute(owner);
	    }

	    if (currentState != null) {
	    	currentState.execute(owner);
	    }
		
	}
}
